home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / PROGRAMM / CC_C / 0924.ZIP / SMIO.LIB < prev    next >
Text File  |  1988-03-09  |  17KB  |  452 lines

  1. /* SMC standard    IO library */
  2. #list-
  3.  
  4. /* PRINTF/SPRINTF/FPRINTF ROUTINES - Variadic input from SMC;
  5.    fprintf uses    putc (and sbrk)    and printf uses    MSDOS Fn 2 */
  6. printf    (fs) char **fs;    { int _psc(); return _prout (stdout, fs, _psc);    }
  7. fprintf    (fs) char **fs;    { int putc(); return _prout (*fs,  --fs, putc);    }
  8. sprintf    (fs) char **fs;    { int _pss(), c; c = _prout (fs,   --fs, _pss);
  9.                       **fs = 0;    return c; }
  10. _prout (fp, pp,    wr) int    *pp, (*wr)();
  11.      {    static char c, pd, *s, *bpt, *fs, buf[30];
  12.     static int lj, ln, wd, pr, tt; fs = *pp--;
  13.     while (c = *fs++)
  14.     {  if (c != '%')
  15.        {  if (c == 0x0A && (*wr) (0x0D, fp)    == EOF)    return EOF;
  16.           if ((*wr)    (c, fp)    != EOF)    continue;  else    return EOF; }
  17.         bpt    = buf; lj = wd = tt = 0; pr = -1;
  18.         if (*fs == '-') { ++fs; ++lj; }
  19.         pd = (*fs == '0') ?    '0' : '    ';
  20.         while ((c =    *fs) >=    '0' && c <= '9')
  21.         {  wd = 10 * wd + c    - '0'; ++fs; }
  22.         if (*fs == '.') { ++fs; pr = 0;
  23.         while ((c =    *fs) >=    '0' && c <= '9')
  24.         {  pr = 10 * pr + c    - '0'; ++fs; } }
  25.  
  26.         switch (toupper (c = *fs++))
  27.         {  case 'D':  if (*pp < 0) { *bpt++    = '-'; *pp = -*pp; }
  28.            case 'U':  _ffdig (*pp, &bpt, 10);
  29.               *bpt = '\0'; bpt = buf; break;
  30.            case 'O':  _ffdig (*pp, &bpt, 8);
  31.               *bpt = '\0'; bpt = buf; break;
  32.            case 'X':  _ffdig (*pp, &bpt, 16);
  33.               *bpt = '\0'; bpt = buf; break;
  34.            case 'E':   tt =    -1; goto fpr;
  35.            case 'F':   tt =     1; goto fpr;
  36.            case 'G':   tt =     0;
  37.          fpr:       if (pr < 0) pr = 6;
  38.               _fprt    (*(float*)(pp -= 2), buf, pr, tt);
  39.                if (*buf == ' ') ++bpt; tt =    0; break;
  40.            case 'S':   bpt = *pp; tt = 1; break;
  41.            case 'C':  *bpt++ = *pp;    *bpt-- = '\0'; break;
  42.            default :  if ((*wr) (c,    fp) != EOF) continue;
  43.               else return EOF;   }
  44.         s =    bpt; while (*s++); ln =    s - bpt    - 1;
  45.         if (tt && pr >= 0 && ln > pr) ln = pr; wd =    wd - ln;
  46.         if (!lj)
  47.         {  if (pd == '0' &&    *bpt ==    '-')
  48.            {  --ln;    if ((*wr) (*bpt++, fp) == EOF) return EOF; }
  49.         while (wd-- > 0)
  50.         if ((*wr) (pd, fp) == EOF) return EOF; }
  51.         while ((c =    *bpt++)    && ln--)
  52.         {    if (c == 0x0A && (*wr) (0x0D, fp) == EOF) return EOF;
  53.         if ((*wr) (c,  fp) == EOF) return EOF; }
  54.         while (wd--    > 0)
  55.         if ((*wr) (pd, fp) == EOF) return EOF;
  56.         --pp; }
  57.     return 0; } /* End of _prout */
  58.  
  59. /* Dummy print *'s for floats */
  60. _fprt (f, b, p,    t) float f; char *b;
  61.      {    t = 8; while (t--) *b++    = '*'; *b = 0; }
  62.  
  63. /* Dummy 2-arg putchar for printf */
  64. _psc (c, z) { bdos (2, c); return c; }
  65.  
  66. /* String output for sprintf */
  67. _pss (c, p) char **p; {    if (c != 0x0D) *(*p)++ = c; return c; }
  68.  
  69.  
  70. /* POSITION SCREEN CURSOR - needs ANSI.SYS INSTALLED */
  71. scrloc (x, y) int x, y;
  72.      {    static char b[18], *p; p = b;
  73.     *p++ = '\33'; *p++ = '[';
  74.     _ffdig (y, &p, 10); *p++ = ';';
  75.     _ffdig (x, &p, 10); *p++ = 'H';
  76.     *p = 0;    putstr (b); }
  77.  
  78. /* Recursive numeral print routine */
  79. _ffdig (n, ptr,    base) unsigned n; char **ptr;
  80.      {     if (n < base) { *(*ptr)++ = '0' + n + (n > 9 ?    7 : 0);    return;    }
  81.     _ffdig (n / base, ptr, base); _ffdig (n    % base,    ptr, base); }
  82.  
  83.  
  84. /* CONSOLE INPUT/OUTPUT    FUNCTIONS */
  85. /* Put string\n    to stdout */
  86. puts (s) char *s;
  87.      {    static char *t;    t = s; while (*t) putch    (*t++);
  88.     putch ('\n'); return s;    }
  89.  
  90. /* Get stdin line (80 chars max) to s -    returns    NULL if    EOF */
  91. gets (s) char *s;
  92.      {    static int c; static char *t; t    = s;
  93.     do {  while ((c    = getc (stdin))    == 0x0D);
  94.           if (c == 0x0A || c == EOF) break;
  95.           *t++ = c;    } while    ((t - s) < 78);
  96.     *t = 0;    return ((t == s    && c ==    EOF) ?    NULL : s ); }
  97.  
  98. /* Put single character    to stdout */
  99. putch (c) { if (c == 0x0A) bdos    (2, 0x0D); bdos    (2, c);    return c; }
  100.  
  101. /* Get single stdin character (no EOF) with stdout repeat */
  102. getch()      { static v;  while ((v = bdos    (8, 0))    == 0x0A);
  103.         bdos (2, v); if (v == 0x0D)    bdos (2, v = 0x0A); return v; }
  104.  
  105. /* Test    if input ready - returns 0 if none */
  106. keyhit() { return bdos (0x0B, 0); }
  107.  
  108. /* Get raw (extended code) input - no repeat - returns 0 if nul    */
  109. rawin ()  { inline ( 0x31, 0xDB, 0xB4, 0x06, 0xB2, 0xFF, 0xCD, 0x21,
  110.              0x74, 0x0E, 0x88, 0xC3, 0x08, 0xDB, 0x75, 0x08,
  111.              0xB4, 0x06, 0xB2, 0xFF, 0xCD, 0x21, 0x88, 0xC7 ); }
  112.  
  113. /* Put string to stdout    - MSDOS    Fn 6 (Control chars off) except    \n. */
  114. /* NB use only to display whole    ASCII lines without tabs */
  115. putstr (s) char    *s;
  116.      {    inline ( 0x89, 0xE5, 0x8B, 0x7E, 0x02, 0x31, 0xDB,
  117.          0x8A, 0x05, 0x47, 0x08, 0xC0, 0x74, 0x1B,
  118.          0x43, 0x3C, 0x0A, 0x74, 0x08, 0x88,
  119.          0xC2, 0xB4, 0x06, 0xCD, 0x21, 0xEB, 0xEC,
  120.          0xB2, 0x0D, 0xB4, 0x02, 0xCD, 0x21,
  121.          0xB2, 0x0A, 0xB4, 0x02, 0xCD, 0x21, 0xEB, 0xDE    ); }
  122.  
  123. /* Getchar/Putchar fetch/require \r as well as \n, and getchar waits
  124.    until \n received - but correctly returns EOF on stdin reassignment.    */
  125. putchar    (c) { return putc (c, stdout); }
  126. getchar    ()  { return getc (stdin); }
  127.  
  128.  
  129. /* BUFFERED SEQUENTIAL FILE INPUT/OUTPUT SYSTEM    */
  130. /* File    open - modes "r", "a" and "w" byte sequential. */
  131. FILE * fopen (s, m) char *s, *m;
  132.      {    static FILE *q;    static int c, fd;
  133.     if ((c = toupper (*m)) != 'R' &&
  134.          c != 'A' && c != 'W') return NULL;
  135.     for (q = _iob; q < _iob    + _NFIL; ++q)
  136.     if (!(q->_bflg & (_READ    | _WRITE))) break;
  137.     if (q >= _iob +    _NFIL) return NULL;
  138.     if (c == 'W') fd = creat (s, 0);
  139.     else if    (c == 'A')
  140.     {  if ((fd = open (s, 1)) == -1)
  141.        fd =    creat (s, 0); seek (fd,    0, 2); }
  142.     else if    (c == 'R') fd =    open (s, 0);
  143.     if (fd == -1) return NULL; q->_bfd = fd;
  144.     q->_bflg |= (c == 'R') ? _READ : _WRITE;
  145.     q->_bptr = NULL; q->_bcnt = 0; return q; }
  146.  
  147. exit (n)
  148.      {    static FILE *q;
  149.     for (q = _iob; q < _iob    + _NFIL; ++q)
  150.     if (q->_bflg & (_READ |    _WRITE)) fclose    (q);
  151.     _exit (n); }
  152.  
  153. fclose (f) FILE    *f;
  154.      {    static FILE *q;    static int n, v; v = n = 0;
  155.     if ((q = f)->_bflg & _WRITE)
  156.     {  if (!(q->_bflg & (_UNBUF | _ERR)) &&    q->_bptr &&
  157.           (v = n = q->_bptr    - q->_bbase) > 0)
  158.        v = write (q->_bfd, q->_bbase, n); }
  159.     else if    (!(q->_bflg & _READ)) return -1;
  160.     v = (close (q->_bfd) ==    -1 || v    != n ||    q->_bflg & _ERR);
  161.     if (q->_bflg & _UNBUF) q->_bbase = NULL; q->_bflg = 0;
  162.     return v ? -1 :    0; }
  163.  
  164. getc (f) FILE *f;  /* Reads all    bytes -    \r as well as \n */
  165.      {    static FILE *q;
  166.     if (--((q = f)->_bcnt) >= 0) goto getok;
  167.     if (!(q->_bflg & _READ)    || (q->_bflg & (_EOF | _ERR))) goto geter;
  168.     if (!q->_bbase && !(q->_bbase =    (FILE *) sbrk (_BSIZ)))
  169.     {  q->_bflg |= _ERR; goto geter; }
  170.     q->_bcnt = read    (q->_bfd, q->_bptr = q->_bbase,
  171.             (q->_bflg & _UNBUF) ? 1    : _BSIZ);
  172.     if (--(q->_bcnt) >= 0) goto getok;
  173.     q->_bflg |= (q->_bcnt == -1 ? _EOF : _ERR);
  174.      geter:  q->_bcnt =    0; return EOF;
  175.      getok:  return *(q->_bptr)++; }
  176.  
  177. ungetc (v, f) FILE *f; /* NB will not accept chars after EOF */
  178.      {    static FILE *q;
  179.     if (!((q = f)->_bflg & _READ) || ! q->_bbase ||    ! q->_bptr ||
  180.           q->_bptr == q->_bbase) return EOF;
  181.     ++q->_bcnt; return *--q->_bptr = v; }
  182.  
  183. putc (v, f) FILE *f; /*    Requires all bytes - \r    as well    as \n */
  184.      {    static FILE *q;    static int n;
  185.     if (!((q = f)->_bflg & _WRITE))    return EOF;
  186.     if (--(q->_bcnt) >= 0) return *(q->_bptr)++ = v;
  187.     if (q->_bflg & _ERR) goto puter;
  188.     if (!q->_bbase && !(q->_bbase =    (FILE *) sbrk (_BSIZ)))
  189.     {  q->_bflg |= _ERR; goto puter; }
  190.     if (!q->_bptr)
  191.     {  q->_bptr = q->_bbase; q->_bcnt = _BSIZ - 2; }
  192.     *(q->_bptr)++ =    v; if (q->_bcnt    >= 0) return v;
  193.     q->_bcnt = write (q->_bfd, q->_bptr = q->_bbase,
  194.              n = (q->_bflg & _UNBUF) ? 1 : _BSIZ);
  195.     if ((q->_bcnt)-- == n) return v;
  196.     q->_bflg |= _ERR;
  197.      puter:  q->_bcnt =    0; return EOF; }
  198.  
  199.  
  200. /* STORAGE AND HEAP MANAGEMENT */
  201. /* Allocate n cleared units of specified size */
  202. calloc (n, size) unsigned n, size;
  203.     {    static unsigned    t; static char *p, *s;
  204.     p = s =    malloc (t = n *    size);
  205.     if (p == NULL) return NULL; while (t--)    *s++ = 0; return p; }
  206.  
  207. /* Allocate formatted block of nb bytes    */
  208. malloc (nb) unsigned nb;
  209.      {    static _mhdr  *p, *q; static unsigned nt;
  210.     nt = 1 + (nb + (sizeof(_mhdr) -    1)) / sizeof(_mhdr);
  211.     if ( !(q = _last) )
  212.          {     _base._mptr = _last = q = &_base; _base._msiz = 0; }
  213.     for (p = q->_mptr; ; q = p, p =    p->_mptr)
  214.          {     if (p->_msiz >= nt)
  215.          {   if    (p->_msiz != nt)
  216.              {    p->_msiz -= nt;    p += p->_msiz; p->_msiz    = nt; }
  217.              else  q->_mptr = p->_mptr;
  218.             _last = q; p->_mptr    = -1; return ++p; }
  219.          if (p == _last)
  220.          {   if    ( !(p =    sbrk(nt    * sizeof(_mhdr)))) return NULL;
  221.              p->_msiz =    nt; free (++p);    p = _last; }
  222.       }         }    /* End of malloc */
  223.  
  224. /* Free    formatted block    */
  225. free(b)    _mhdr *b;
  226.      {    static _mhdr *p, *q; p = b-1;
  227.     for (q = _last;    ; q = q->_mptr)
  228.         if ((q < p && q->_mptr > p)    ||
  229.         (q->_mptr <= q &&
  230.         (p > q || p < q->_mptr)    )) break;
  231.     if (p +    p->_msiz != q->_mptr) p->_mptr = q->_mptr;
  232.     else { p->_msiz    += q->_mptr->_msiz; p->_mptr = q->_mptr->_mptr;    }
  233.     if (q +    q->_msiz != p) q->_mptr    = p;
  234.     else { q->_msiz    += p->_msiz; q->_mptr =    p->_mptr; }
  235.        _last = q; }
  236.  
  237. /* Get unformatted heap    string - requires heap
  238.    start/end addresses set at DS:0x100/0x102 at    loadtime */
  239. sbrk (n) unsigned n;
  240.      {    static char **hc, **hm,    *hn;
  241.     hc = 0x100; hm = 0x102;    hn = *hc + n;
  242.     return (hn >= *hc && hn    < *hm) ? (*hc =    hn) - n    : NULL;    }
  243.  
  244.  
  245. /* STRING AND CHARACTER    FUNCTIONS */
  246. atoi (s) char *s;
  247.      {    static int m, v; m = v = 0;
  248.     while (*s == ' ' || *s == '\t')    ++s;
  249.     if (*s == '+' || *s == '-') m =    (*s++ == '-');
  250.     while (*s >= '0' && *s <= '9') v = 10 *    v + (*s++ - '0');
  251.     return m ? -v :    v; }
  252.  
  253. isalpha    (c)
  254.   {  /*    if ( c >= 'a' && c <= 'z' ) return 1;
  255.     return ( c >= 'A' && c <= 'Z' ); */
  256.     inline ( 0x89, 0xE5, 0x8A, 0x46, 0x02, 0x31, 0xDB,
  257.          0x3C, 0x41, 0x72, 0x0D, 0x3C, 0x5B, 0x72, 0x08,
  258.          0x3C, 0x61, 0x72, 0x05, 0x3C, 0x7B, 0x73, 0x01, 0x43 ); }
  259.  
  260. isdigit    (c)
  261.   {  /*    return ( c >= '0' && c <= '9' ); */
  262.     inline ( 0x89, 0xE5, 0x8A, 0x46, 0x02, 0x31, 0xDB,
  263.          0x3C, 0x30, 0x72, 0x05, 0x3C, 0x3A, 0x73, 0x01, 0x43 ); }
  264.  
  265. isalnum    (c)
  266.   {  /*    if ( c >= '0' && c <= '9' ) return 1;
  267.     if ( c >= 'a' && c <= 'z' ) return 1;
  268.     return ( c >= 'A' && c <= 'Z' ); */
  269.     inline ( 0x89, 0xE5, 0x8A, 0x46, 0x02, 0x31, 0xDB,
  270.          0x3C, 0x30, 0x72, 0x15, 0x3C, 0x3A, 0x72, 0x10,
  271.          0x3C, 0x41, 0x72, 0x0D, 0x3C, 0x5B, 0x72, 0x08,
  272.          0x3C, 0x61, 0x72, 0x05, 0x3C, 0x7B, 0x73, 0x01, 0x43 ); }
  273.  
  274. isspace    (c)  { return (c == ' '    || c ==    '\t' ||    c == '\r' || c == '\n'); }
  275.  
  276. strcpy (d, s) char *s, *d;
  277.   {  /*    do *d++    = *s; while (*s++); */
  278.     inline ( 0x89, 0xE5, 0x8B, 0x76, 0x02, 0x8B, 0x7E, 0x04, 0x8A,
  279.          0x04, 0x88, 0x05, 0x46, 0x47, 0x08, 0xC0, 0x75, 0xF6 ); }
  280.  
  281. strlen (s) char    *s;
  282.      {    inline ( 0x89, 0xE5, 0x8B, 0x5E, 0x02, 0xB9, 0xFF, 0xFF, 0x8A,
  283.          0x07, 0x43, 0x41, 0x08, 0xC0, 0x75, 0xF8, 0x89, 0xCB ); }
  284.  
  285. strcmp(s, t) char *s, *t;
  286.   {  /*    while (*s == *t) { if (!*s) return 0; ++s; ++t;    } return *s - *t; */
  287.     inline ( 0x89, 0xE5, 0x8B, 0x5E, 0x04, 0x8B, 0x7E, 0x02, 0x8A,
  288.          0x07, 0x3A, 0x05, 0x75, 0x0C, 0x08, 0xC0, 0x74, 0x04,
  289.          0x47, 0x43, 0xEB, 0xF2, 0x31, 0xDB, 0xEB, 0x0A, 0x88,
  290.          0xC3, 0xB7, 0x00, 0x8A, 0x05, 0xB4, 0x00, 0x29, 0xC3 ); }
  291.  
  292. strucmp(s, t) char *s, *t;
  293. /* compare with    cases equivalent */
  294.   {  static char p, q;
  295.      while ((p = toupper (*s)) == (q = toupper (*t)))
  296.      { if (!p) return 0; ++s; ++t; } return p -    q; }
  297.  
  298. toupper    (c) {  return (c >= 'a'    &&  c <= 'z') ?    c - 0x20 : c; }
  299.  
  300. tolower    (c) {  return (c >= 'A'    &&  c <= 'Z') ?    c + 0x20 : c; }
  301.  
  302.  
  303. /* SHELL SORT */
  304. sort (f, c, s, n) char *(*f)();    int (*c)(), s, n;
  305. /* f(i)    must return address of the i'th    data item; c(p,    q) must
  306.    return true if item *p is correctly sequenced before    item *q;
  307.    s is    sizeof(item) and n is the number of items to sort. */
  308.      {    static int g, i, j, k, u; static char *p, *q;
  309.     for (g = n >> 1; g > 0;    g >>= 1)
  310.     for (i = g; i <    n; ++i)
  311.     for (j = i - g;    j >= 0;    j -= g)
  312.      {    if ((*c)(p = (*f)(j), q    = (*f)(j + g)))    break;
  313.     for (k = 0; k <    s; ++k)    { u = *p; *p++ = *q; *q++ = u; } } }
  314.  
  315.  
  316. /* RANDOM NUMBER GENERATOR */
  317. /* Seed    from MSDOS timer byte */
  318. rand() {  if (!_rval) _rval = epeek (0,    0x46C);
  319.      _rval ^= ( _rval >> 4 ); _rval    ^= ( _rval << 11 );
  320.      _rval &= 0x7FFF; return _rval;    }
  321.  
  322.  
  323. /* MEMORY FUNCTIONS */
  324. /* Extended peek - byte    from segment, offset */
  325. epeek (seg, off)
  326.      { inline (    0x89, 0xE5, 0x8B, 0x56,    0x04, 0x8B, 0x5E, 0x02,
  327.         0x06, 0x8E, 0xC2, 0x26,    0x8A, 0x1F, 0xB7, 0x00,    0x07 );    }
  328.  
  329. /* Extended poke - byte    to segment, offset */
  330. epoke (val, seg, off)
  331.      { inline (    0x89, 0xE5, 0x8B, 0x56,    0x04, 0x8B, 0x5E, 0x02,    0x8A,
  332.         0x46, 0x06, 0x06, 0x8E,    0xC2, 0x26, 0x88, 0x07,    0x07 );    }
  333.  
  334. /* Execute in the data segment - mcp points to code array,
  335.    bx, cx and di are entry values for BX, CX and DI.
  336.    Code    must terminate with C3 near return. Returns BX.    */
  337. mcrun (bx, cx, di, mcp)
  338.   {  static char *bp, mx[] =
  339.      { 0x8B, 0x07, 0x43, 0x43, 0x8B, 0x3F, 0x43, 0x43,
  340.        0x8B, 0x0F, 0x43, 0x43, 0x8B, 0x1F, 0x50, 0xC3 };
  341.        bp = &mcp; asm (mx, &bp); return    bp; }
  342.  
  343. /* Execute in the data segment - mcp points to code array, bxp points to
  344.    to int containing BX    value on entry,    and set    to BX value on exit.
  345.    Code    must terminate with C3 near return. Returns 16-bit flags value.    */
  346. asm (mcp, bxp)
  347.      {    inline ( 0x89, 0xE5, 0x8B, 0x4E, 0x04, 0x8B, 0x5E, 0x02,
  348.          0x53, 0x8B, 0x1F, 0x0E, 0xE8, 0x00, 0x00, 0x5A,
  349.          0x83, 0xC2, 0x0C, 0x52, 0xBA, "\313",       0x52,
  350.          0x1E, 0x51, 0xCB, 0x5F, 0x89, 0x1D, 0x9C, 0x5B    ); }
  351.  
  352.  
  353. /* OPERATING SYSTEM FUNCTIONS */
  354. /* Execute a MSDOS command - returns 0 if OK else Int 4B error code */
  355. system (s) char    *s;
  356.      {    static int i, pb[7]; static char *p, *cc = "C:COMMAND.COM",
  357.     fc[] = "         ",    cl[50] = { 0, '/', 'C',    ' ' };
  358.     for (p = cl + 4, i = 0;    *s && i    < 44; ++i) *p++    = *s++;
  359.     *p++ = 0x0D; *p    = 0; *cl = i + 3;
  360.     inline ( 0xBD, pb,   0x8C, 0xDB, 0xC7, 0x46, 0x00, 0x00, 0x00,
  361.          0xC7, 0x46, 0x02, cl,     0x89, 0x5E, 0x04,
  362.          0xC7, 0x46, 0x06, fc,     0x89, 0x5E, 0x08,
  363.          0xC7, 0x46, 0x0A, fc,     0x89, 0x5E, 0x0C,
  364.          0x16, 0x5F, 0x89, 0xE3, 0x2E, 0x89, 0x1E, 0xF8, 0x00,
  365.          0x2E, 0x89, 0x3E, 0xFA, 0x00, 0xBB, pb,   0x8B, 0x16, &cc,
  366.          0xB8, 0x00, 0x4B, 0xCD, 0x21, 0x2E, 0x8B, 0x1E, 0xF8,
  367.          0x00, 0x2E, 0x8B, 0x3E, 0xFA, 0x00, 0x8E, 0xD7, 0x89,
  368.          0xDC, 0x89, 0xC3, 0x72, 0x02, 0x31, 0xDB ); }
  369.  
  370. /* Set FCB from    name - returns value 0 if OK,
  371.    1 if    OK but with wildcards, FF if invalid */
  372. _fcbx (nm, fcb)
  373.      {    inline ( 0x89, 0xE5, 0x8B, 0x76, 0x04, 0x8B, 0x7E, 0x02,
  374.          0x57, 0xB8, 0x01, 0x29, 0xCD, 0x21, 0x5F, 0x83,
  375.          0xC7, 0x20, 0xB9, 0x04, 0x00, 0xC6, 0x05, 0x00,
  376.          0x47, 0xE2, 0xFA, 0x88, 0xC3, 0xB7, 0x00 ); }
  377.  
  378.  
  379. /* SYSTEM LEVEL    FILE I/O - NB Error code is -1 */
  380. creat (name, mode) char    *name;
  381.      {    /* Modes 00/04 normal/system R/W, 01/05    normal/system R/O */
  382.     inline ( 0x89, 0xE5, 0x8B, 0x56, 0x04, 0x8B, 0x4E, 0x02,
  383.          0xB4, 0x3C, 0xCD, 0x21, 0x89, 0xC3,
  384.          0x73, 0x03, 0xBB, -1 ); }
  385.  
  386. open (name, mode) char *name;
  387.      {    /* Modes 0 read, 1 write, 2 r/w    */
  388.     inline ( 0x89, 0xE5, 0x8B, 0x56, 0x04, 0x8A, 0x46, 0x02,
  389.          0xB4, 0x3D, 0xCD, 0x21, 0x89, 0xC3,
  390.          0x73, 0x03, 0xBB, -1 ); }
  391.  
  392. close (fd)
  393.      {    inline ( 0x89, 0xE5, 0x8B, 0x5E, 0x02,
  394.          0xB4, 0x3E, 0xCD, 0x21, 0xBB, 0x00, 0x00,
  395.          0x73, 0x03, 0xBB, -1 ); }
  396.  
  397. read (fd, buf, ct) char    *buf;
  398. /* returns #read, else 0 EOF or    -1 error */
  399.      {    inline ( 0x89, 0xE5, 0x8B, 0x5E, 0x06,
  400.          0x8B, 0x56, 0x04, 0x8B, 0x4E, 0x02,
  401.          0xB4, 0x3F, 0xCD, 0x21, 0x89, 0xC3,
  402.          0x73, 0x03, 0xBB, -1 ); }
  403.  
  404. write (fd, buf,    ct) char *buf;
  405. /* returns #written, else 0 disk full or -1 error */
  406.      {    inline ( 0x89, 0xE5, 0x8B, 0x5E, 0x06,
  407.          0x8B, 0x56, 0x04, 0x8B, 0x4E, 0x02,
  408.          0xB4, 0x40, 0xCD, 0x21, 0x89, 0xC3,
  409.          0x73, 0x03, 0xBB, -1 ); }
  410.  
  411. seek (fd, off, org) /* NB SIGNED off, org */
  412. /* org = 0/3 for beginning, 1/4    for current or 2/5 for eof;
  413.    if org = 3, 4 or 5 offset is    multiplied by 0x200,
  414.    returns LSW of absolute byte    offset from start of file */
  415.      {    static int ff, oh, ol, og; ff =    fd;
  416.     if ((og    = org) < 0) return -1;
  417.     else if    (og <= 2) { oh = (off <    0) ? -1    : 0; ol    = off; }
  418.     else if    (og <= 5) { oh = off >>    7; ol =    off << 9; og -=    3; }
  419.     else return -1;
  420.     inline ( 0x8B, 0x1E, &ff,  0xA0, &og,  0x8B, 0x0E, &oh,
  421.          0x8B, 0x16, &ol,  0xB4, 0x42, 0xCD, 0x21, 0x89, 0xC3,
  422.          0x73, 0x03, 0xBB, -1 ); }
  423.  
  424. reopen (fa, fb)
  425. /* sets    fa as duplicate    of file    handle fb */
  426.      {    inline ( 0x89, 0xE5, 0x8B, 0x4E, 0x04, 0x8B, 0x5E, 0x02,
  427.          0xB4, 0x46, 0xCD, 0x21, 0xBB, 0x00, 0x00,
  428.          0x73, 0x03, 0xBB, -1 ); }
  429.  
  430. rename (old, new) char *old, *new;
  431. /* rename a file - but no wildcards */
  432.      {    inline ( 0x89, 0xE5, 0x8B, 0x56, 0x04, 0x8B, 0x7E, 0x02,
  433.          0xB4, 0x56, 0xCD, 0x21, 0xBB, 0x00, 0x00,
  434.          0x73, 0x03, 0xBB, -1 ); }
  435.  
  436. unlink (name) char *name;
  437. /* delete a file */
  438.      {    inline ( 0x89, 0xE5, 0x8B, 0x56, 0x02,
  439.          0xB4, 0x41, 0xCD, 0x21, 0xBB, 0x00, 0x00,
  440.          0x73, 0x03, 0xBB, -1 ); }
  441.  
  442. /* Exit    to system with return code n */
  443. _exit (n) { inline ( 0x89, 0xE5, 0x8A, 0x46, 0x02,
  444.              0xB4, 0x4C, 0xCD, 0x21 ); }
  445.  
  446. /* Basic OS call - returns AL value */
  447. bdos (ah, dx) {    inline ( 0x89, 0xE5, 0x8A, 0x66, 0x04, 0x8B, 0x56, 0x02,
  448.              0xCD, 0x21, 0x88, 0xC3, 0xB7, 0x00 ); }
  449.  
  450. /* End of SMIO.LIB */
  451. #list+
  452.